#include "zrpc/base/logger.h"
#include "zrpc/net/tcp_client.h"
#include "zrpc/rpc/rpc_channel.h"
#include "sudoku.pb.h"

class RpcClient {
 public:
  RpcClient(zrpc::EventLoop* loop, const std::string& ip, int16_t port)
      : loop_(loop),
        client_(loop, ip, port, nullptr),
        channel_(new zrpc::RpcChannel),
        stub_(channel_.get()),
        count_(0) {
    client_.SetConnectionCallback(
        std::bind(&RpcClient::OnConnection, this, std::placeholders::_1));
    client_.SetMessageCallback(std::bind(&zrpc::RpcChannel::OnMessage,
                                         channel_.get(), std::placeholders::_1,
                                         std::placeholders::_2));
  }

  void Connect() { client_.Connect(); }

 private:
  void OnConnection(const std::shared_ptr<zrpc::TcpConnection>& conn) {
    if (conn->Connected()) {
      channel_->SetConnection(conn);
      for (int i = 0; i < 1000000; i++) {
        sudoku::SudokuRequest request;
        request.set_checkerboard("001010");
        sudoku::SudokuResponse* response = new sudoku::SudokuResponse;

        stub_.Solve(nullptr, &request, response,
                    NewCallback(this, &RpcClient::Sloved, response));
      }
    } else {
      loop_->Quit();
    }
  }

  void Sloved(sudoku::SudokuResponse* resp) { LOG_INFO << count_++; }

  zrpc::EventLoop* loop_;
  zrpc::TcpClient client_;
  zrpc::RpcChannelPtr channel_;
  sudoku::SudokuService::Stub stub_;
  uint32_t count_;
};

int main() {
  zrpc::EventLoop loop;
  RpcClient rpc_client(&loop, "127.0.0.1", 6379);
  rpc_client.Connect();
  loop.Run();
}